package com.itlong.cloud.property.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.itlong.cloud.POJO.DTO.property.PropertyValueServerSaveDTO;
import com.itlong.cloud.POJO.DTO.property.PropertyValueServerSaveDeployDTO;
import com.itlong.cloud.POJO.PO.*;
import com.itlong.cloud.POJO.VO.property.PropertyValueServerGetOneVO;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.constants.RabbitMQConstant;
import com.itlong.cloud.enumerate.CloudElevatorChangeBusinessEnum;
import com.itlong.cloud.enumerate.CloudEntranceChangeBusinessEnum;
import com.itlong.cloud.enumerate.SmartCommunityEnum;
import com.itlong.cloud.property.dao.IPropertyAccountDao;
import com.itlong.cloud.property.dao.IPropertyRoomInfoDao;
import com.itlong.cloud.property.dao.IPropertyValueServerDao;
import com.itlong.cloud.property.service.IPropertyValueServerService;
import com.itlong.cloud.rabbitmq.config.MessageSender;
import com.itlong.cloud.utils.data.handler.SqlUtil;
import com.itlong.cloud.utils.node.JsonUtil;
import com.itlong.cloud.utils.random.LogicIdUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

/**
 * <desc>
 *      物业-物业增值业务处理接口实现类
 * </desc>
 *
 * @createDate 2019/05/29
 */
@Service
public class PropertyValueServerServiceImpl  implements IPropertyValueServerService {

    private static final Logger LOG = LoggerFactory.getLogger(PropertyValueServerServiceImpl.class);

    @Autowired
    IPropertyAccountDao iPropertyAccountDao;

    @Autowired
    IPropertyRoomInfoDao iPropertyRoomInfoDao;

    @Autowired
    private MessageSender messageSender;

    @Autowired
    IPropertyValueServerDao iPropertyValueServerDao;

    /**
     * <desc>
     *     处理过期临时通行房间
     * <desc/>
     *
     * @return  MessageVO 标准格式化响应结果
     * @author Qiang.S
     * @createDate 2019/05/31
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public Map<String, Set<String>> doTemporaryOverdue() throws Exception {
        // 欠费状态，0未欠费，1已欠费
        Date nowTime = new Date();
        List<PropertyPaymentBillPO> listPo = iPropertyAccountDao.getUserIdForBill();
        // 用于更新房间欠费状态
        Set<String> roomSet = new HashSet<>();
        // 用于发送消息队列设备轮询命令存储数据
        Map<String, Set<String>> roomIdMapSet = new HashMap<>();
        for (PropertyPaymentBillPO po : listPo) {
            List<String> roomIds = iPropertyAccountDao.getRoomIdByUserId(po.getUserId(),po.getProjectId());
            if (roomIds != null && !roomIds.isEmpty()) {
                // 放入待更新欠费状态的房间Set中
                roomSet.addAll(roomIds);
                // 放入发送消息队列设备轮询命令数据中
                if (roomIdMapSet.get(po.getProjectId()) == null) {
                    Set<String> set = new HashSet<>(roomIds);
                    roomIdMapSet.put(po.getProjectId(),set);
                } else {
                    Set<String> set = roomIdMapSet.get(po.getProjectId());
                    set.addAll(roomIds);
                    roomIdMapSet.put(po.getProjectId(),set);
                }
                // 更新账单临时通行过期处理标记为已处理
                iPropertyAccountDao.updateTemproparyFlag(po.getFeeId(),1);
            }
        }
        //LOG.info("临时通行权限回收待推送指令房间：" + roomIdMapSet);

        // 查询过期的临时解除限制信息
        List<MomentRelievePO> momentRelievePOList = iPropertyRoomInfoDao.getOverdueMomentRelieve();
        List<String> momentRoomList = new ArrayList<>();
        for (MomentRelievePO po : momentRelievePOList) {
            // 放入待更新欠费状态的房间Set中
            roomSet.add(po.getRoomId());
            // 放入待删除临时解除限制的房间List中
            momentRoomList.add(po.getRoomId());
            // 放入发送消息队列设备轮询命令数据中
            if (roomIdMapSet.get(po.getProjectId()) == null) {
                Set<String> set = new HashSet<>();
                set.add(po.getRoomId());
                roomIdMapSet.put(po.getProjectId(),set);
            } else {
                Set<String> set = roomIdMapSet.get(po.getProjectId());
                set.add(po.getRoomId());
                roomIdMapSet.put(po.getProjectId(),set);
            }
        }
        if (!momentRoomList.isEmpty()) {
            iPropertyRoomInfoDao.deleteMomentRelieve(momentRoomList);
        }

        // 更新房屋欠费状态和用户项目欠费状态
        for (String roomId : roomSet) {
            // 更新房间欠费状态
            RoomInfoPO roomInfoPO = new RoomInfoPO();
            roomInfoPO.setRoomId(roomId);
            roomInfoPO.setArrearageStatus("1");
            roomInfoPO.setUpdateTime(nowTime);
            Map<String, Object> map = SqlUtil.durableData(roomInfoPO, PlatformConstants.TABLE_UPDATE);
            iPropertyRoomInfoDao.update(map);
            // 通过房间id查询房间下的住户
            List<String> userIdList = iPropertyRoomInfoDao.getUserIdsByRoomId(roomId);
            for (String userId : userIdList) {
                // 判断用户项目下是否还有欠费房间，没有则更新用户项目为不欠费状态
                int arrearRoomCount = iPropertyRoomInfoDao.getArrearRoomCount(roomId, userId);
                // 更新用户项目欠费状态
                if (arrearRoomCount == 0) {
                    iPropertyRoomInfoDao.updateUserProjectArrearageStatus(roomId,0, userId);
                } else {
                    iPropertyRoomInfoDao.updateUserProjectArrearageStatus(roomId,1, userId);
                }
            }
        }

        //LOG.info("临时解除+临时通行权限回收待推送指令房间：" + roomIdMapSet);

        // 推送设备指令
        roomIdMapSet.forEach((key, value) -> {
            try {
                List<DeviceBusinessChangeLogPO> changes = new ArrayList<>();
                List<DeviceBusinessElevatorChangeLogPO> elevatorChanges = new ArrayList<>();
                List<DeviceBusinessEntranceChangeLogPO> entranceChanges = new ArrayList<>();
                List<Map<String,Object>> roomList=new ArrayList<>();
                for (String roomId : value) {
                    Map<String,Object> roomMap=new HashMap<>();
                    roomMap.put("roomId", roomId);
                    roomList.add(roomMap);
                }
                //推送房间更新消息
                DeviceBusinessChangeLogPO po = new DeviceBusinessChangeLogPO(SmartCommunityEnum.PUSH_ROOM, JsonUtil.toJSON(roomList), key);
                changes.add(po);
                DeviceBusinessElevatorChangeLogPO elevatorPo = new DeviceBusinessElevatorChangeLogPO(key, CloudElevatorChangeBusinessEnum.PUSH_ROOM_PWD, JsonUtil.toJSON(roomList));
                elevatorChanges.add(elevatorPo);
                DeviceBusinessEntranceChangeLogPO entrancePO = new DeviceBusinessEntranceChangeLogPO(key, CloudEntranceChangeBusinessEnum.PUSH_ROOM_PWD, JsonUtil.toJSON(roomList));
                entranceChanges.add(entrancePO);
                JSONObject dataJs = new JSONObject();
                dataJs.put("data", changes);
                //发送云对讲业务指令
                messageSender.send(RabbitMQConstant.RABBITMQ_HANDLE_SMART_COMMUNITY_ORDERS_QUEUE, JsonUtil.toJSON(dataJs),
                        RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_EXCHANGE,
                        RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_ROUTING_KEY);
                dataJs.put("data", elevatorChanges);
                //推送云电梯房间信息
                messageSender.send(
                        RabbitMQConstant.RABBITMQ_HANDLE_CLOUD_ELEVATOR_CHANGE_BUSINESS_QUEUE,
                        JsonUtil.toJSON(dataJs),
                        RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_EXCHANGE,
                        RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_ROUTING_KEY);
                //发送云门禁指令
                dataJs.put("data", entranceChanges);
                messageSender.send(
                        RabbitMQConstant.RABBITMQ_HANDLE_CLOUD_ENTRANCE_CHANGE_BUSINESS_QUEUE,
                        JSON.toJSONString(dataJs),
                        RabbitMQConstant.RABBITMQ_CLOUD_ENTRANCE_CHANGE_BUSINESS_EXCHANGE,
                        RabbitMQConstant.RABBITMQ_CLOUD_ENTRANCE_CHANGE_BUSINESS_ROUTING_KEY
                );
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
        return roomIdMapSet;
    }

    /**
     * <desc>
     *      获取单个对象
     * </desc>
     *
     * @return
     * @author Jiaqi.X
     * @createDate 2019/05/29
     */
    @Override
    public PropertyValueServerGetOneVO getOne(String projectId) {
        PropertyValueServerGetOneVO vo = iPropertyValueServerDao.getOne(projectId);
        if(vo !=null && StringUtils.isNotBlank(vo.getModuleId())) {
            //获取物业配置
            vo.setArrearsLevels(iPropertyValueServerDao.getDeploys(projectId));
        }
        return vo;
    }

    /**
     * <desc>
     *      保存物业增值配置
     * </desc>
     *
     * @param dto
     * @return
     * @author Jiaqi.X
     * @createDate 2019/05/29
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public String save(PropertyValueServerSaveDTO dto) throws Exception {
        PropertyValuePO po = new PropertyValuePO();
        po.setPropertyValueId(dto.getModuleId());
        po.setUpdateTime(new Date());
        po.setProjectId(dto.getProjectId());
        po.setDeploy(dto.getLowerHairProperty());
        po.setOpenTempPass(dto.getTempPass());
        if(StringUtils.isNotBlank(dto.getTempPassMoney())) {
            po.setTempPassMoney(new BigDecimal(dto.getTempPassMoney()));
        }
        po.setTempPassOpenTime(dto.getTempOpenTime());
        po.setOpenDeviceType(dto.getOpenDevice());
        //保存修改信息
        iPropertyValueServerDao.update(SqlUtil.durableData(po, PlatformConstants.TABLE_UPDATE));
        //保存配置信息
        List<PropertyValueServerSaveDeployDTO> list = dto.getArrearsLevels();
        for(PropertyValueServerSaveDeployDTO deploy : list){
            PropertyValueDeployPO dp = new PropertyValueDeployPO();
            dp.setPropertyValueDeployId(iPropertyValueServerDao.getPropertyValueDeployIdByModuleId(po.getPropertyValueId(), deploy.getType()));
            if(StringUtils.isBlank(dp.getPropertyValueDeployId())){
                //保存
                dp.setPropertyValueDeployId(LogicIdUtil.userBusinessId());
                dp.setCreateTime(new Date());
            }else{
                //修改
                dp.setPropertyValueDeployId(dp.getPropertyValueDeployId());
                dp.setUpdateTime(new Date());
            }
            dp.setProjectId(dto.getProjectId());
            dp.setPropertyValueId(po.getPropertyValueId());
            dp.setLevel(deploy.getType());
            dp.setDay(deploy.getDay());
            dp.setPointOut(deploy.getPointOut());
            dp.setElevatorDeployLimit(deploy.getElevator());
            dp.setEntranceDeployLimit(deploy.getEntrance());
            dp.setCloudIntercomLimit(deploy.getCloudTalk());
            dp.setPhoneDeployLimit(deploy.getPhone());
            iPropertyValueServerDao.update(SqlUtil.durableData(dp,PlatformConstants.TABLE_UPDATE));
        }
        //推送设备项目信息
        //云对讲
        JSONObject talkObject = new JSONObject();
        talkObject.put("projectId",dto.getProjectId());
        List<DeviceBusinessChangeLogPO> changeLogPOS = new ArrayList<>();
        changeLogPOS.add(new DeviceBusinessChangeLogPO(SmartCommunityEnum.PUSH_PROJECT, talkObject, dto.getProjectId()));
        JSONObject talkJs = new JSONObject();
        talkJs.put("data", changeLogPOS);
        messageSender.send(
                RabbitMQConstant.RABBITMQ_HANDLE_SMART_COMMUNITY_ORDERS_QUEUE,
                JSON.toJSONString(talkJs),
                RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_EXCHANGE,
                RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_ROUTING_KEY
        );
        //云电梯
        //项目信息变更通知云电梯
        JSONObject elevatorObject = new JSONObject();
        elevatorObject.put("projectId",dto.getProjectId());
        List<DeviceBusinessElevatorChangeLogPO> changeLogPOs = new ArrayList<>();
        changeLogPOs.add(new DeviceBusinessElevatorChangeLogPO(dto.getProjectId(), CloudElevatorChangeBusinessEnum.PUSH_PROJECT,elevatorObject.toJSONString()));
        JSONObject elevatorJs = new JSONObject();
        elevatorJs.put("data",changeLogPOs);
        messageSender.send(
                RabbitMQConstant.RABBITMQ_HANDLE_CLOUD_ELEVATOR_CHANGE_BUSINESS_QUEUE,
                JsonUtil.toJSON(elevatorJs),
                RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_EXCHANGE,
                RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_ROUTING_KEY);
        //项目信息变更通知云门禁
        JSONObject entranceObject = new JSONObject();
        entranceObject.put("projectId",dto.getProjectId());
        List<DeviceBusinessEntranceChangeLogPO> changeLogEntrance = new ArrayList<>();
        changeLogEntrance.add(new DeviceBusinessEntranceChangeLogPO(CloudEntranceChangeBusinessEnum.PUSH_PROJECT, entranceObject,dto.getProjectId()));
        JSONObject entranceJs = new JSONObject();
        entranceJs.put("data", changeLogEntrance);
        //发送云门禁指令
        messageSender.send(
                RabbitMQConstant.RABBITMQ_HANDLE_CLOUD_ENTRANCE_CHANGE_BUSINESS_QUEUE,
                JSON.toJSONString(entranceJs),
                RabbitMQConstant.RABBITMQ_CLOUD_ENTRANCE_CHANGE_BUSINESS_EXCHANGE,
                RabbitMQConstant.RABBITMQ_CLOUD_ENTRANCE_CHANGE_BUSINESS_ROUTING_KEY
        );
        return po.getPropertyValueId();
    }

}
